package the.broccoli.uc.service.impl;

import com.google.common.collect.Lists;
import com.sun.org.apache.regexp.internal.RE;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import the.broccoli.ac.entity.Res;
import the.broccoli.ac.service.IResService;
import the.broccoli.uc.controller.req.UpdateAppReq;
import the.broccoli.uc.dto.AdminUserAddDTO;
import the.broccoli.uc.dto.BuyAppDTO;
import the.broccoli.uc.dto.TenantAddDTO;
import the.broccoli.uc.entity.Role;
import the.broccoli.uc.entity.RoleRes;
import the.broccoli.uc.entity.Tenant;
import the.broccoli.uc.entity.TenantApp;
import the.broccoli.uc.mapper.TenantAppMapper;
import the.broccoli.uc.mapper.TenantMapper;
import the.broccoli.uc.service.IRoleResService;
import the.broccoli.uc.service.IRoleService;
import the.broccoli.uc.service.ITenantService;
import org.wisteria.framework.web.mvc.service.AbstractSuperService;
import org.springframework.stereotype.Service;
import the.broccoli.uc.service.IUserService;

import javax.annotation.Resource;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lei.liu
 * @since 2020-04-11
 */
@Slf4j
@Service
public class TenantServiceImpl extends AbstractSuperService<TenantMapper, Tenant> implements ITenantService {

    @Resource
    private TenantAppMapper tenantAppMapper;

    @Resource
    private IUserService userService;

    @Resource
    private IRoleService roleService;

    @Resource
    private IResService resService;

    @Resource
    private IRoleResService roleResService;

    @Override
    public String getTenantNameById(Integer tenantId) {
        if (tenantId == null) {
            return null;
        }

        Tenant tenant = this.baseMapper.selectById(tenantId);
        if (tenant == null) {
            return null;
        }
        return tenant.getTenantName();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean add(TenantAddDTO dto) {
        Tenant tenant = new Tenant();
        tenant.setTenantName(dto.getTenantName());
        this.baseMapper.insert(tenant);

        Role adminRole = roleService.addAndGetTenantAdmin(tenant.getTenantId(), dto.getOperatorId(), dto.getOperatorName());

        AdminUserAddDTO admin = new AdminUserAddDTO();
        admin.setAccount(dto.getAccount());
        admin.setTenantId(tenant.getTenantId());
        admin.setUserName(dto.getUserName());
        admin.setPassword(dto.getPassword());
        admin.setOperatorId(dto.getOperatorId());
        admin.setOperatorName(dto.getOperatorName());
        admin.setRoleId(adminRole.getRoleId());
        userService.addAdminUser(admin);




        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean buyApp(BuyAppDTO dto) {
        if (CollectionUtils.isEmpty(dto.getAppIdList())) {
            return false;
        }

        TenantApp tenantApp = null;
        for (Integer appId : dto.getAppIdList()) {
            tenantApp = new TenantApp();
            tenantApp.setTenantId(dto.getTenantId());
            tenantApp.setAppId(appId);
            tenantApp.setCreatedTime(new Date());
            tenantApp.setCreatedId(dto.getOperatorId());
            tenantApp.setCreatedName(dto.getOperatorName());
            tenantApp.setModifiedTime(new Date());
            tenantApp.setModifiedId(dto.getOperatorId());
            tenantApp.setModifiedName(dto.getOperatorName());
            tenantAppMapper.insert(tenantApp);
        }

        Role adminRole = roleService.addAndGetTenantAdmin(dto.getTenantId(), dto.getOperatorId(), dto.getOperatorName());

//        List<String> resIdList = resService.getResIdList(dto.getAppIdList().stream().map(String::valueOf).collect(Collectors.toList()));
        List<Res> resList = resService.listByAppIdBatch(dto.getAppIdList());
        if (!CollectionUtils.isEmpty(resList)) {
            List<RoleRes> roleResList = new ArrayList<>();
            RoleRes roleRes = null;
            for (Res res : resList) {
                roleRes = new RoleRes();
                roleRes.setRoleId(adminRole.getRoleId());
                roleRes.setResId(res.getResId());
                roleRes.setAppId(res.getAppId());
                roleResList.add(roleRes);
            }
            roleResService.saveBatch(roleResList, roleResList.size());
        }

        return true;
    }

    /**
     * 更新应用资源信息
     */
    @Transactional
    @Override
    public boolean updateApp(UpdateAppReq req) {
        Role adminRole = roleService.getTenantAdmin(req.getTenantId());
        if (adminRole == null) {
            log.info("租户无管理员角色。TenantId:{}", req.getTenantId());
            return false;
        }

        List<Res> resList = resService.listByAppIdBatch(Lists.newArrayList(req.getAppId()));
        if (CollectionUtils.isEmpty(resList)) {
            log.info("应用无资源数据。AppId:{}", req.getAppId());
            return false;
        }

        roleResService.removeAppResOfRole(adminRole.getRoleId(), req.getAppId());

        List<RoleRes> roleResList = new ArrayList<>();
        RoleRes roleRes = null;
        for (Res res : resList) {
            roleRes = new RoleRes();
            roleRes.setRoleId(adminRole.getRoleId());
            roleRes.setResId(res.getResId());
            roleRes.setAppId(res.getAppId());
            roleResList.add(roleRes);
        }
        roleResService.saveBatch(roleResList, roleResList.size());

        return true;
    }
}
